/*
 * @(#)Schema.java	1.0 2000/12/19
 *
 * Copyright 2000 Thomas Barnekow. All Rights Reserved.
 *
 * This software is the proprietary information of Thomas Barnekow.
 * Use is subject to license terms.
 */

package tb.provider.jdbc;

import java.sql.*;
import java.util.*;

import tb.provider.*;
import tb.util.*;

/**
 * Schema metadata.
 *
 * @author Thomas Barnekow
 * @version 1.0
 */
public class Schema extends AbstractCompoundMetaObject implements NamedObject {

  private QualifiedName m_qn;

  public static final String[] TYPES = new String[] {
    Table.TYPE_TABLE, Table.TYPE_VIEW
  };

  Schema(String name, Database database) {
    super(name, database);
    m_qn = new QualifiedName(name);
  }

  /*
   * AbstractCompoundMetaObject operations
   */

  protected Collection createElementCollection() throws SQLException {
    return Collections.unmodifiableCollection(getTables());
  }

  public MetaObject get(Comparable id) {
    if (id instanceof QualifiedName) {
      QualifiedName tableName = ((QualifiedName) id).toLowerCase();
      if (tableName.getNamespaceName().equals(getQualifiedName()))
        return super.get(tableName.getLastNameComponent());
      else
        return null;
    } else {
      return super.get(id.toString().toLowerCase());
    }
  }

  /*
   * NamedObject operations
   */

  public QualifiedName getQualifiedName() {
    return m_qn;
  }

  /*
   * This class' operations
   */

  public final Connection getConnection() {
    return ((Database) getContainer()).getConnection();
  }

  /**
   * Get all tables of type TABLE and VIEW.
   */
  public final List getTables() throws SQLException {
    return getTables("%");
  }

  public final List getTables(String tableNamePattern) throws SQLException {
    return getTables(tableNamePattern, TYPES);
  }

  public final List getTables(String tableNamePattern, String[] types)
    throws SQLException
  {
    List tables = new ArrayList();

    ResultSet result = getConnection().getMetaData().getTables(
      null, getId().toString().toUpperCase(), tableNamePattern.toUpperCase(), types);

    while (result.next()) {
			String table = result.getString(3).toLowerCase();
			String type = result.getString(4);
			String remarks = result.getString(5);

      tables.add(new Table(table, type, remarks, this));
    }
    result.close();
    Collections.sort(tables);

    // Done
    return Collections.unmodifiableList(tables);
  }

  public Table findTable(String name)
    throws NoSuchElementException, SQLException
  {
    return findTable(getTables(name), name);
  }

  public Table findTable(String tableNamePattern, String name)
    throws NoSuchElementException, SQLException
  {
    return findTable(getTables(tableNamePattern), name);
  }

  public Table findTable(String tableNamePattern, String[] types, String name)
    throws NoSuchElementException, SQLException
  {
    return findTable(getTables(tableNamePattern, types), name);
  }

  public static Table findTable(List tables, String name)
    throws NoSuchElementException
  {
    int pos = Collections.binarySearch(tables, name);
    if (pos >= 0)
      return (Table) tables.get(pos);
    else
      throw new NoSuchElementException(String.valueOf(name));
  }
}